<template>
    <el-dialog :title="dialogFrom.dialogTitle" :model-value="dialogFrom.dialogVisible" class="user-ruleForm"
        @input:model-value="updateDialogVisible" align-center width="60%" :before-close="onCancel">
        <el-form ref="unifiedFormRef" :model="dataInfo" :rules="rules" label-width="100px" class="demo-ruleForm">
            <el-form-item label="用户名" prop="username">
                <el-input v-model="dataInfo.username" placeholder="请填写用户名" clearable :disabled="dialogFrom.infoId === 1"></el-input>
            </el-form-item>
            <el-form-item label="密码" prop="password" v-if="!dialogFrom.infoId">
                <el-input v-model="dataInfo.password" show-password placeholder="请填写密码" clearable></el-input>
            </el-form-item>
            <el-form-item label="昵称" prop="nickName">
                <el-input v-model="dataInfo.nickName" placeholder="请填写昵称" clearable></el-input>
            </el-form-item>
            <el-form-item label="电话" prop="phone">
                <el-input v-model="dataInfo.phone" placeholder="请填写电话" :maxlength="11" clearable></el-input>
            </el-form-item>
            <el-form-item label="邮箱" prop="email">
                <el-input v-model="dataInfo.email" placeholder="请填写邮箱" clearable></el-input>
            </el-form-item>
            <el-form-item label="居住地址" prop="address">
                <el-input v-model="dataInfo.address" placeholder="请填写居住地址" clearable></el-input>
            </el-form-item>
            <el-form-item label="头像" prop="profilePicture">
                <el-upload class="user-avatar-uploader" action="#" :show-file-list="false"
                    :before-upload="beforeUserAvatarUpload" :http-request="handleUserAvatarUpload">
                    <img v-if="imageUrl" :src="VUE_APP_BASE_API + imageUrl" class="user-avatar" />
                    <el-icon v-else class="user-avatar-uploader-icon">
                        <Plus />
                    </el-icon>
                </el-upload>
            </el-form-item>
        </el-form>
        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="onSubmit(unifiedFormRef)" :loading="loading">提交</el-button>
                <el-button @click="onCancel">取消</el-button>
            </div>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
// -------------------------------------------------导入相关引用-------------------------------------------------

import { ref, watch } from 'vue';
import { ElMessage, type FormInstance, type FormRules, type UploadRequestOptions } from 'element-plus'
import type { DataInfo } from '@/api/system/SysUser'
import { getInfo, saveInfo, editInfo } from '@/api/system/SysUser'
import { uploadFile } from '@/api/communal'
// -------------------------------------------------相关参数定义-------------------------------------------------
const loading = ref(false);
const VUE_APP_BASE_API = process.env["VUE_APP_BASE_API"];
const props = withDefaults(defineProps<{
    dialogFrom: DialogFrom
}>(), {
    dialogFrom: () => ({
        dialogTitle: '',
        dialogVisible: false,
        infoId: null,
    })
});

const unifiedFormRef = ref<FormInstance | undefined>(undefined);

const rules: FormRules = {
    username: [
        { required: true, message: '用户名不能为空', trigger: 'blur' }
    ],
    password: [
        { required: true, message: '密码不能为空', trigger: 'blur' },
        {
            validator: (rule: any, value: string, callback: any) => {
                const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,20}$/;
                if (!regex.test(value)) {
                    callback(new Error('密码需包含大小写字母、数字、特殊符号(!@#$%^&*)，长度8-20位'));
                } else {
                    callback();
                }
            }, trigger: 'blur'
        }
    ],
    nickName: [
        { required: true, message: '昵称不能为空', trigger: 'blur' }
    ],
    phone: [
        { required: true, message: '电话不能为空', trigger: 'blur' },
        {
            validator: (rule: any, value: string, callback: any) => {
                const regex = /^1[3456789]\d{9}$/;
                if (!regex.test(value)) {
                    callback(new Error('请输入正确的手机号码'));
                } else {
                    callback();
                }
            }, trigger: 'blur'
        }
    ],
    email: [
        { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
    ]
}

const imageUrl = ref('');

const initData = {
    id: null,
    username: '',
    password: '',
    nickName: '',
    phone: '',
    email: '',
    address: '',
    profilePicture: '',
}

const dataInfo = ref<DataInfo>({ ...initData })

// ---------------------------------------------------事件定义--------------------------------------------------

const emit = defineEmits(['update:dialogFrom', 'onParentSearch']);

// -------------------------------------------------操作方法定义-------------------------------------------------

/**
 * 监听dialogFrom参数
 */
watch(() => props.dialogFrom.dialogVisible, (newValue, oldValue) => {
    if (newValue) {
        getInfoApi();
    }
})

/**
 * 文件上传
 * @param options 文件信息
 */
const handleUserAvatarUpload = (options: UploadRequestOptions) => {
    const formData = new FormData();
    formData.append("file", options.file, options.file.name)
    formData.append("currentDir", "userAvatar");
    uploadFile(formData).then((res) => {
        if (res.data.code === 200) {
            dataInfo.value.profilePicture = res.data.data.fileUrl;
            imageUrl.value = res.data.data.fileUrl
            ElMessage.success({
                message: '头像上传成功',
                type: 'success'
            })
        }
    })
}

/**
 * 文件上传之前
 * @param file 文件
 */
const beforeUserAvatarUpload = (file: any) => {
    const isLt1M = file.size / 1024 / 1024 < 1;
    if (!file.type.includes('image')) {
        ElMessage.error('上传头像只能是图片格式!');
        return false;
    }
    if (!isLt1M) {
        ElMessage.error('上传头像图片大小不能超过1MB!');
        return false;
    }
}

/**
 * 获取表单信息
 */
const getInfoApi = async () => {
    const infoId = props.dialogFrom.infoId;
    if (infoId) {
        await getInfo(infoId).then((res) => {
            if (res.data.code === 200) {
                dataInfo.value = res.data.data;
                imageUrl.value = res.data.data.profilePicture;
            }
        })
    }
}

/**
 * 提交表单
 */
const onSubmit = async (ref: FormInstance | undefined) => {
    if (!ref) return
    loading.value = true
    await ref.validate((valid, fields) => {
        if (valid) {
            if (props.dialogFrom.infoId) {
                editInfo(dataInfo.value).then((res) => {
                    loading.value = false
                    if (res.data.code === 200) {
                        ElMessage.success({
                            message: '修改成功',
                            type: 'success'
                        })
                        onCancel();
                    }
                })
            } else {
                saveInfo(dataInfo.value).then((res) => {
                    loading.value = false
                    if (res.data.code === 200) {
                        ElMessage.success({
                            message: '添加成功',
                            type: 'success'
                        })
                        onCancel();
                    }
                })
            }
        } else {
            loading.value = false
        }
    })
}

/**
 * 关闭弹窗
 */
const onCancel = () => {
    resetFrom();
    emit('update:dialogFrom', {
        dialogVisible: false,
        dialogTitle: '',
        infoId: null
    });
    emit('onParentSearch');
}

/**
 * 重置表单
 */
const resetFrom = () => {
    dataInfo.value = {
        ...initData
    }
    imageUrl.value = '';
}

/**
 * 更新弹窗显示状态
 * @param dialogFromParams
 * @returns void
 */
const updateDialogVisible = (dialogFromParams: DialogFrom) => {
    emit('update:dialogFrom', dialogFromParams);
}

// -------------------------------------------------实体定义区-------------------------------------------------

/**
 * 弹窗信息
 */
export interface DialogFrom {
    dialogTitle: string;
    dialogVisible: boolean;
    infoId: number | null;
}
</script>

<style lang="scss" scoped>
.user-avatar-uploader .user-avatar {
    width: 120px;
    height: 120px;
    display: block;
}
</style>

<style>
.user-avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.user-avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.user-avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 120px;
    height: 120px;
    text-align: center;
}
</style>